package com.tim.app.ui.fragment.message;

import android.content.res.Configuration;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v7.widget.LinearLayoutManager;
import android.text.TextUtils;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.LinearLayout;

import com.application.library.base.BaseFragment;
import com.application.library.runtime.event.EventListener;
import com.application.library.runtime.event.EventManager;
import com.application.library.widget.EmptyLayout;
import com.application.library.widget.loadmore.LoadMoreContainer;
import com.application.library.widget.loadmore.LoadMoreHandler;
import com.application.library.widget.recycle.BaseRecyclerAdapter;
import com.application.library.widget.recycle.WrapRecyclerView;
import com.netease.nim.session.SessionHelper;
import com.netease.nimlib.sdk.NIMClient;
import com.netease.nimlib.sdk.Observer;
import com.netease.nimlib.sdk.RequestCallbackWrapper;
import com.netease.nimlib.sdk.ResponseCode;
import com.netease.nimlib.sdk.msg.MsgService;
import com.netease.nimlib.sdk.msg.MsgServiceObserve;
import com.netease.nimlib.sdk.msg.constant.SessionTypeEnum;
import com.netease.nimlib.sdk.msg.model.IMMessage;
import com.netease.nimlib.sdk.msg.model.RecentContact;
import com.tim.app.R;
import com.tim.app.constant.EventTag;
import com.tim.app.server.entry.User;
import com.tim.app.server.logic.UserManager;
import com.tim.app.ui.adapter.message.RecentContactAdapter;
import com.tim.app.ui.popup.ActionPop;
import com.tim.app.ui.view.MessageHeadView;
import com.tim.app.util.ViewGT;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.Map;

/**
 * 消息页面
 */
public class MessageFragment extends BaseFragment implements LoadMoreHandler, BaseRecyclerAdapter.OnItemClickListener, BaseRecyclerAdapter.OnItemLongClickListener {

    // 置顶功能可直接使用，也可作为思路，供开发者充分利用RecentContact的tag字段
    public static final long RECENT_TAG_STICKY = 1; // 联系人置顶tag

    public static final String TAG = "MessageFragment";
    private View rootView;

    private LinearLayout llContainer;
    private WrapRecyclerView wrvMessage;
    private EmptyLayout emptyLayout;
    private MessageHeadView headerView;
    private RecentContactAdapter adapter;

    private List<RecentContact> items;

    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        if (null == rootView) {
            rootView = inflater.inflate(R.layout.fragment_message, container, false);

            llContainer = (LinearLayout) rootView.findViewById(R.id.llContainer);
            wrvMessage = (WrapRecyclerView) rootView.findViewById(R.id.wrvMessage);

            wrvMessage.setOverScrollMode(View.OVER_SCROLL_NEVER);

            emptyLayout = new EmptyLayout(getActivity(), llContainer);
            emptyLayout.showContent();
            emptyLayout.setEmptyDrawable(R.drawable.ic_empty_message);
            emptyLayout.setEmptyText("通过消息与有趣的人亲密交流", "一朵茉莉，两位知己，三味人生，四海之友");
            emptyLayout.setEmptyButtonShow(true);
            emptyLayout.setEmptyButtonText("注册/登录");
            emptyLayout.setEmptyButtonClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    ViewGT.gotoLoginActivity(getContext());
                }
            });

            headerView = (MessageHeadView) inflater.inflate(R.layout.message_head_view, null);

            if (null == items) {
                items = new ArrayList<>();
            }
            LinearLayoutManager layoutManager = new LinearLayoutManager(getActivity());
            layoutManager.setOrientation(LinearLayoutManager.VERTICAL);
            wrvMessage.setLayoutManager(layoutManager);

            wrvMessage.addHeaderView(headerView);

            adapter = new RecentContactAdapter(getActivity(), items);
            adapter.setOnItemClickListener(this);
            adapter.setOnItemLongClickListener(this);
            wrvMessage.setAdapter(adapter);
        }
        EventManager.ins().registListener(EventTag.ACCOUNT_LOGIN, eventListener);
        EventManager.ins().registListener(EventTag.ACCOUNT_LOGOUT, eventListener);
        EventManager.ins().registListener(EventTag.ON_NEW_MESSAGE, eventListener);
        EventManager.ins().registListener(EventTag.ON_UN_READ_MESSAGE_COUNT, eventListener);
        EventManager.ins().registListener(EventTag.ON_NEW_NOTICE, eventListener);
        EventManager.ins().registListener(EventTag.DO_DELETE, eventListener);
        EventManager.ins().registListener(EventTag.ON_OFFICIAL_UNREAD_MESSAGE_CHANGED, eventListener);
        initData();
        registerObservers(true);
        return rootView;
    }

    @Override
    public void onActivityCreated(Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);
    }


    /**
     * ********************** 收消息，处理状态变化 ************************
     */
    private void registerObservers(boolean register) {
        MsgServiceObserve service = NIMClient.getService(MsgServiceObserve.class);
        service.observeMsgStatus(statusObserver, register);
        service.observeRecentContactDeleted(deleteObserver, register);
        service.observeReceiveMessage(incomingMessageObserver, register);
    }


    Observer<List<IMMessage>> incomingMessageObserver =
            new Observer<List<IMMessage>>() {
                @Override
                public void onEvent(List<IMMessage> messages) {
                    requestMessages(true);
                    final int unReadMessageTotalCount = NIMClient.getService(MsgService.class).getTotalUnreadCount();
                    EventManager.ins().sendEvent(EventTag.ON_READ_MESSAGE_COUNT, 0, 0, unReadMessageTotalCount);
                }
            };


    Observer<RecentContact> deleteObserver = new Observer<RecentContact>() {
        @Override
        public void onEvent(RecentContact recentContact) {
            if (recentContact != null) {
                for (RecentContact item : items) {
                    if (TextUtils.equals(item.getContactId(), recentContact.getContactId())
                            && item.getSessionType() == recentContact.getSessionType()) {
                        items.remove(item);
                        refreshMessages(true);
                        break;
                    }
                }
            } else {
                items.clear();
                refreshMessages(true);
            }
            adapter.notifyDataSetChanged();

        }
    };

    Observer<IMMessage> statusObserver = new Observer<IMMessage>() {
        @Override
        public void onEvent(IMMessage message) {
            int index = getItemIndex(message.getUuid());
            if (index >= 0 && index < items.size()) {
                RecentContact item = items.get(index);
                item.setMsgStatus(message.getStatus());
                adapter.notifyDataSetChanged();
            }
        }
    };

    private int getItemIndex(String uuid) {
        for (int i = 0; i < items.size(); i++) {
            RecentContact item = items.get(i);
            if (TextUtils.equals(item.getRecentMessageId(), uuid)) {
                return i;
            }
        }
        return -1;
    }

    EventListener eventListener = new EventListener() {
        @Override
        public void handleMessage(int what, int arg1, int arg2, Object dataobj) {
            switch (what) {
                case EventTag.ACCOUNT_LOGIN:
                case EventTag.ACCOUNT_LOGOUT:
                    initData();
                    break;
                case EventTag.ON_NEW_MESSAGE:
                    items.clear();
                    List<RecentContact> datas = (List<RecentContact>) dataobj;
                    items.addAll(datas);
                    adapter.notifyDataSetChanged();
                    emptyLayout.showContent();
                    break;
                case EventTag.ON_UN_READ_MESSAGE_COUNT:
                    requestMessages(false);
                    break;
                case EventTag.ON_NEW_NOTICE:
                    final int unReadMessageTotalCount = NIMClient.getService(MsgService.class).getTotalUnreadCount();
                    EventManager.ins().sendEvent(EventTag.ON_READ_MESSAGE_COUNT, 0, 0, unReadMessageTotalCount);
                    break;
                case EventTag.DO_DELETE:
                    int position = (int) dataobj;
                    if (items.size() > position) {
                        RecentContact recentContact = items.get(position);
                        NIMClient.getService(MsgService.class).deleteRecentContact(recentContact);
                        items.remove(position);
                        adapter.notifyDataSetChanged();
                    }
                    break;
                case EventTag.ON_OFFICIAL_UNREAD_MESSAGE_CHANGED:
                    headerView.updateUnreadOfficialMessageCount();
                    break;
            }
        }
    };

    private void initData() {
        if (!UserManager.ins().isLogin()) {
            emptyLayout.showEmpty();
        } else {
            emptyLayout.showContent();
            requestMessages(true);
        }
    }

    private void requestMessages(boolean delay) {
        getHandler().postDelayed(new Runnable() {

            @Override
            public void run() {
                // 查询最近联系人列表数据
                NIMClient.getService(MsgService.class).queryRecentContacts().setCallback(new RequestCallbackWrapper<List<RecentContact>>() {

                    @Override
                    public void onResult(int code, List<RecentContact> recents, Throwable exception) {
                        if (code != ResponseCode.RES_SUCCESS || recents == null) {
                            return;
                        }
                        onRecentContactsLoaded(recents);
                    }
                });
            }
        }, delay ? 250 : 0);
    }

    private void onRecentContactsLoaded(List<RecentContact> recents) {
        items.clear();
        if (recents != null) {
            items.addAll(recents);
            adapter.notifyDataSetChanged();
        }
        refreshMessages(true);
    }


    private void refreshMessages(boolean unreadChanged) {
        sortRecentContacts(items);

        if (unreadChanged) {
            // 方式二：直接从SDK读取（相对慢）
            int unreadNum = NIMClient.getService(MsgService.class).getTotalUnreadCount();
            EventManager.ins().sendEvent(EventTag.ON_READ_MESSAGE_COUNT, 0, 0, unreadNum);
        }
    }

    /**
     * **************************** 排序 ***********************************
     */
    private void sortRecentContacts(List<RecentContact> list) {
        if (null == list || list.size() == 0) {
            return;
        }
        Collections.sort(list, comp);
    }

    private static Comparator<RecentContact> comp = new Comparator<RecentContact>() {

        @Override
        public int compare(RecentContact o1, RecentContact o2) {
            // 先比较置顶tag
            long sticky = (o1.getTag() & RECENT_TAG_STICKY) - (o2.getTag() & RECENT_TAG_STICKY);
            if (sticky != 0) {
                return sticky > 0 ? -1 : 1;
            } else {
                long time = o1.getTime() - o2.getTime();
                return time == 0 ? 0 : (time > 0 ? -1 : 1);
            }
        }
    };


    @Override
    public void onItemClick(View view, int position, long id) {
        //因为在Adapter里更新数据了
        RecentContact recentContact = adapter.getDataList().get(position);
        if (!TextUtils.isEmpty(recentContact.getContactId())) {
            User user = new User();
            user.setUserId(recentContact.getContactId());

            Map<String, Object> extension = recentContact.getExtension();
            String name = "";
            if (null != extension && extension.containsKey("name")) {
                name = extension.get("name").toString();
            }
            SessionHelper.startP2PSession(getActivity(), UserManager.ins().getChatId(recentContact.getContactId()), name);
        }
    }

    @Override
    public void onStop() {
        super.onStop();
    }

    @Override
    public void onResume() {
        super.onResume();
        // 进入最近联系人列表界面，建议放在onResume中
        NIMClient.getService(MsgService.class).setChattingAccount(MsgService.MSG_CHATTING_ACCOUNT_ALL, SessionTypeEnum.None);
        requestMessages(false);
    }

    @Override
    public void onPause() {
        super.onPause();
        // 退出聊天界面或离开最近联系人列表界面，建议放在onPause中
        NIMClient.getService(MsgService.class).setChattingAccount(MsgService.MSG_CHATTING_ACCOUNT_NONE, SessionTypeEnum.None);
    }

    @Override
    public void onDestroyView() {
        super.onDestroyView();
        if (null != rootView && null != rootView.getParent()) {
            ((ViewGroup) rootView.getParent()).removeView(rootView);
        }
    }

    @Override
    public boolean onItemLongClick(View view, int position, long id) {
        ActionPop actionPop = new ActionPop(getActivity(), position);
        actionPop.show(wrvMessage);
        return false;
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        registerObservers(false);
        EventManager.ins().removeListener(EventTag.ACCOUNT_LOGIN, eventListener);
        EventManager.ins().removeListener(EventTag.ACCOUNT_LOGOUT, eventListener);
        EventManager.ins().removeListener(EventTag.ON_NEW_MESSAGE, eventListener);
        EventManager.ins().removeListener(EventTag.ON_UN_READ_MESSAGE_COUNT, eventListener);
        EventManager.ins().removeListener(EventTag.ON_NEW_NOTICE, eventListener);
        EventManager.ins().removeListener(EventTag.DO_DELETE, eventListener);
        EventManager.ins().removeListener(EventTag.ON_OFFICIAL_UNREAD_MESSAGE_CHANGED, eventListener);
    }

    @Override
    public void onLoadMore(LoadMoreContainer loadMoreContainer) {

    }

    @Override
    public void onConfigurationChanged(Configuration newConfig) {
        super.onConfigurationChanged(newConfig);
    }


}
